//
//  Iterator.cpp
//  MyTryForMapping2
//
//  Created by Артемий Соболев on 15.05.12.
//  Copyright (c) 2012 avriy@me.com. All rights reserved.
//

#include "main.h"
#include "sorts.h"
#include "logger.cpp"


class Iterator {
public:
    Iterator(char fileName[]){
        fd = open(fileName, O_RDONLY, 0666);
        end = lseek(fd, 0, SEEK_END);
        lseek(fd, 0, SEEK_SET);
        partOfFile = open("part.csv",O_RDWR|O_CREAT, 0666);
        numberToRead = end;
    }
    
    ~Iterator(){
        unlink("part.csv");
        itemsLeft = end;
        count = 0;
    }
    bool haveNext(){
        itemsLeft = end - (count)*buffersiz;
        if ( itemsLeft > 0) return true;   
        else   return false;
    }
    int numberToRead;
    int next(){
        char p[2*buffersiz];
        char *pa;
        itemsLeft = end - (count)*buffersiz;
        if (itemsLeft >= buffersiz) numberToRead = buffersiz;
        else numberToRead = itemsLeft;
        
        
        pa = &p[0];
        
        
        size = read(fd, pa, numberToRead*sizeof(char));
        
        //while (*(pa + numberToRead - right) != ',') right++;
        while (*(pa + numberToRead - right) != ',' & itemsLeft >= buffersiz) right++;
        numberToRead = numberToRead - right;
        
        
        unlink("part.csv");
        partOfFile = open("part.csv",O_RDWR|O_CREAT, 0666);
        write(partOfFile, &temp[0], endNumberSize*sizeof(char));
        write(partOfFile, pa, (numberToRead)*sizeof(char));
        endNumberSize = right;
        
        for(int i = right; i > 0; i--) temp[right - i] = p[numberToRead + 1 + right - i];
        
        right = 0;
        count++;
 //       Logger::Instance().msg(1, "wea");
        return partOfFile;
        
    }
private:
    int fd;
    int endNumber;
    int partOfFile;
    size_t size;
    int endNumberSize;
    int count;
    int end;
    int right;
    char temp[buffersiz];
    int itemsLeft;
};

class Strategy {
public:
    virtual void makeYourJob(int &number){};
};

class BubbleStrategy : public Strategy {
public:
    void makeYourJob(int &number){
        bubbleSort(createTemporaries(number), number);
    }
};

class QsortStrategy : public Strategy {
public:
    void makeYourJob(int &number){
        quickSort(createTemporaries(number), number);
    }
};

class Chooser {
    
private:
    Strategy* strategy_;
    BubbleStrategy bub;
    QsortStrategy qs;
    
public:
    Chooser(): strategy_(){}
    
    void decideWhoWouldBeBetter(int &number){
        
        double temp;
        
        clock_t start;
        clock_t end;
        start = clock();
        qs.makeYourJob(number);
        end = clock();
        temp = end - start;
        start = clock();
        number = -number;
        bub.makeYourJob(number);
        end = clock();
        if (start - end < temp) strategy_ = &bub;
        else strategy_ = &qs;
    
    }
    
    void makeYourJob(int &number){
       return strategy_->makeYourJob(number);
    }
};